package com.mask.im.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mask.im.business.model.entity.chat.Friendships;
import com.mask.im.business.common.exception.BusinessException;
import com.mask.im.business.mapper.IMFriendGroupsMapper;
import com.mask.im.business.mapper.FriendshipsMapper;
import com.mask.im.business.model.dto.FriendGroupDTO;
import com.mask.im.business.model.dto.LazyGetFriendDTO;
import com.mask.im.business.common.model.RestResponse;
import com.mask.im.business.model.entity.chat.IMFriendGroupsDO;
import com.mask.im.business.model.vo.UpdateFriendGroupVO;
import com.mask.im.business.service.IMFriendGroupsService;
import com.mask.im.business.common.util.BeanCopy;
import com.mask.im.business.common.util.MaskIMSecurityUtils;
import com.mask.token.util.MaskSecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 群组管理
 *
 * @author jian
 */
@Service
public class IMFriendGroupsServiceImpl extends ServiceImpl<IMFriendGroupsMapper, IMFriendGroupsDO> implements IMFriendGroupsService {


    @Autowired
    private FriendshipsMapper friendshipsMapper;

    @Override
    public RestResponse<List<IMFriendGroupsDO>> getCurrentAllGroup() {
        Integer userId = MaskIMSecurityUtils.getUserId();
        List<IMFriendGroupsDO> imFriendGroups = this.baseMapper.selectList(new LambdaQueryWrapper<IMFriendGroupsDO>()
                .eq(IMFriendGroupsDO::getUserInfoId, userId).orderByAsc(IMFriendGroupsDO::getSort));
        return RestResponse.ok(imFriendGroups);
    }

    @Override
    public RestResponse<List<FriendGroupDTO>> getFriendGroup() {
        Long userInfoId = MaskSecurityUtil.getCurrentUserId();
        List<IMFriendGroupsDO> imFriendGroups = this.baseMapper.selectList(new LambdaQueryWrapper<IMFriendGroupsDO>()
                .eq(IMFriendGroupsDO::getUserInfoId, userInfoId).orderByAsc(IMFriendGroupsDO::getSort));
        List<FriendGroupDTO> friendGroupDTOS = BeanCopy.listCopy(imFriendGroups, FriendGroupDTO.class);
        List<FriendGroupDTO> friendGroupDTOList = friendGroupDTOS.stream()
                .peek(item -> item.setChildren(lazyGetFriend(item.getId())))
                .collect(Collectors.toList());
        return RestResponse.ok(friendGroupDTOList);
    }

    public List<LazyGetFriendDTO> lazyGetFriend(Long groupId) {
        Long userInfoId = MaskSecurityUtil.getCurrentUserId();
        return friendshipsMapper.lazyGetFriend(userInfoId, groupId);
    }

    @Override
    public RestResponse<String> addFriendGroup(IMFriendGroupsDO imFriendGroups) {
        Integer count = this.baseMapper.selectCount(new LambdaQueryWrapper<IMFriendGroupsDO>()
                .eq(IMFriendGroupsDO::getGroupName, imFriendGroups.getGroupName()));
        if (count > 0) {
            throw new BusinessException("分组名已存在，不能重复创建");
        }
        imFriendGroups.setUserInfoId(MaskIMSecurityUtils.getUseLongId());
        this.baseMapper.insert(imFriendGroups);
        return RestResponse.ok();
    }

    @Override
    public RestResponse<String> deleteFriendGroup(Integer groupId) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        Integer count = friendshipsMapper
                .selectCount(new LambdaQueryWrapper<Friendships>()
                        .eq(Friendships::getGroupId, groupId));
        if (count > 0) {
            throw new BusinessException("分组下仍有好友，不能直接删除");
        }
        IMFriendGroupsDO IMFriendGroups = this.baseMapper.selectById(groupId);
        if (!userId.equals(IMFriendGroups.getUserInfoId())) {
            throw new BusinessException("删除错误");
        }
        this.baseMapper.deleteById(groupId);
        return RestResponse.ok();
    }

    @Override
    public RestResponse<String> updateFriendGroup(Integer groupId, String groupName, Integer sort) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        IMFriendGroupsDO selectById = this.baseMapper.selectById(groupId);
        if (!userId.equals(selectById.getUserInfoId())) {
            throw new BusinessException("修改错误");
        }
        this.baseMapper.update(null, new LambdaUpdateWrapper<IMFriendGroupsDO>()
                .set(IMFriendGroupsDO::getSort, sort)
                .set(IMFriendGroupsDO::getGroupName, groupName)
                .eq(IMFriendGroupsDO::getId, groupId));
        return RestResponse.ok();
    }

    @Override
    public RestResponse<IMFriendGroupsDO> getByIdGroup(Integer groupId) {
        IMFriendGroupsDO IMFriendGroups = this.baseMapper.selectById(groupId);
        return RestResponse.ok(IMFriendGroups);
    }

    @Override
    public RestResponse<IMFriendGroupsDO> getBelongsGroup(Integer friendId) {
        Integer userInfo = MaskIMSecurityUtils.getUserId();
        Friendships friendships = friendshipsMapper.selectOne(new LambdaQueryWrapper<Friendships>()
                .select(Friendships::getGroupId)
                .eq(Friendships::getOneUserId, userInfo)
                .eq(Friendships::getTwoUserId, friendId));
        IMFriendGroupsDO IMFriendGroups = this.baseMapper.selectById(friendships.getGroupId());
        return RestResponse.ok(IMFriendGroups);
    }

    @Override
    public RestResponse<IMFriendGroupsDO> moveFriendGroup(UpdateFriendGroupVO updateFriendGroupVO) {
        Integer userId = MaskIMSecurityUtils.getUserId();
        IMFriendGroupsDO imFriendGroups = this.baseMapper.selectOne(new LambdaQueryWrapper<IMFriendGroupsDO>()
                .eq(IMFriendGroupsDO::getId, updateFriendGroupVO.getGroupId())
                .eq(IMFriendGroupsDO::getUserInfoId, userId));
        if (Objects.isNull(imFriendGroups)) {
            throw new BusinessException("分组名不存在,请重试");
        }
        friendshipsMapper.update(null, new LambdaUpdateWrapper<Friendships>()
                .set(Friendships::getGroupId, updateFriendGroupVO.getGroupId())
                .eq(Friendships::getOneUserId, userId)
                .eq(Friendships::getTwoUserId, updateFriendGroupVO.getFriendId()));
        return RestResponse.ok();
    }
}

